/*
 * curvebuf.hpp
 *
 *  Created on: 2018年1月16日
 *      Author: work
 */

#ifndef _DM_CURVEBUF_HPP_
#define _DM_CURVEBUF_HPP_

namespace dm{

/**
 * 曲线缓冲区
 */
template<typename T>
class TCCurveBuf{
public:
	TCCurveBuf( T* buf,const int& size ):m_buf(buf),m_size(size),m_s(0),m_e(0){
	}

	virtual ~TCCurveBuf(){
	}

	virtual int refreshAndGetFirstChanged();

	/**
	 * 获取点数
	 * @return
	 */
	inline int getCount()const{
		return m_e>m_s?m_e-m_s:m_size-m_s+m_e;
	}

	/**
	 * 获取数值
	 * @param idx 数据索引。注意不是缓冲区索引。
	 * @return
	 */
	inline const T& getValue( const int& idx )const{
		int i = m_s + idx;
		i %= m_size;
		return m_buf[i];
	}

	bool getMaxMin( T& max,T& min )const;
protected:
	/**
	 * 追加数据
	 * @param v
	 */
	inline void append( const T& v ){
		m_buf[m_e] = v;
		move(m_e);
		if( m_s==m_e )
			move(m_s);
	}

	/**
	 * 移动指针
	 * @param p
	 */
	inline void move( int& p )const{
		++p;
		if( p>=m_size )
			p = 0;
	}

protected:
	T* m_buf;	// 数据缓冲区
	int m_size;	// 缓冲区大小

	int m_s;	// 起始位置
	int m_e;	// 结束位置
};

/**
 * 刷新曲线，并返回第一个更新的点索引。一般由子类来实现。
 * - -1 无更新
 * - 0 全部更新
 * >0 部分更新
 * @return
 */
template<typename T>
int TCCurveBuf<T>::refreshAndGetFirstChanged(){
	return 0;
}

/**
 * 获取最大最小值
 * @param max
 * @param min
 */
template<typename T>
boo TCCurveBuf<T>::getMaxMin( T& max,T& min )const{
	if( m_s==m_e )
		return false;

	int i = m_s;
	max = m_buf[i];
	min = m_buf[i];

	move(i);
	while( i!=m_e ){
		if( m_buf[i]<min )
			min = m_buf[i];
		if( m_buf[i]>max )
			max = m_buf[i];

		move(i);
	}

	return true;
}

typedef TCCurveBuf<float> CFloatCurveBuf;
typedef TCCurveBuf<int> CIntCurveBuf;

}

#endif /* DM_RUNTIME_INCLUDE_DM_CURVEBUF_HPP_ */
